from pyglet.gl import glViewport, glMatrixMode, glLoadIdentity, GL_MODELVIEW, glOrtho, glScalef, GL_PROJECTION
from bipy.components import Component

class ViewManager(Component):
    def __init__(self):
        super(ViewManager, self).__init__('viewmanager', 500)
        self.__view_groups = []
        self.__current_group = []
        self.new_view = View
        
    def add_view(self, view):
        if view not in self.__current_group:
            self.__current_group.append(view)
            
    def add_views(self, views):
        for view in views:
            self.add_view(view)
            
    def remove_view(self, view):
        if view in self.__current_group:
            self.__current_group.remove(view)
    def remove_views(self, views):
        for view in views:
            self.remove_view(view)

    def push_views(self, views):
        if self.__current_group:
            self.__view_groups.append(self.__current_group)
        self.__current_group = views

    def pop_views(self):
        if self.__view_groups:
            self.__current_group = self.__view_groups.pop()
        else:
            self.__current_group = None

    def get_views(self):
        return self.__current_group
        
    def reset_view(self):
        glViewport( 0, 0, self.dynamic.width, self.dynamic.height)
        glMatrixMode( GL_PROJECTION )
        glLoadIdentity()
        glOrtho( 0.0, self.dynamic.width, 0.0, self.dynamic.height, -1.0, 1.0)
        glMatrixMode( GL_MODELVIEW )
        glLoadIdentity()

component_class = ViewManager

class View(object):
    """
    Represents a viewport of the world.
    """
    def __init__(self,
                state,
                world_pos=(0.0, 0.0, 1.0),
                world_dir=(0.0, 0.0, 0.0),
                screen_pos=(0.0, 0.0),
                screen_size=(640.0, 480.0),
                zoom=1.0,
                far=1.0):
        self.x, self.y, self.z = world_pos
        self.rx, self.ry, self.rz = world_dir
        self.screen_x, self.screen_y = screen_pos
        self.screen_w, self.screen_h = screen_size
        self._far = far
        self.zoom = zoom
    def on_resize(self, width, height):
        self.screen_w, self.screen_h = width, height
        
    def set_viewport(self):
        """
        Sets this viewport as the current render target.
        """
        glViewport( int(self.screen_x), int(self.screen_y), int(self.screen_w), int(self.screen_h))
        glMatrixMode( GL_PROJECTION )
        glLoadIdentity()
        glOrtho( self.x - self.screen_w/2., self.x + self.screen_w/2., self.y - self.screen_h/2., self.y + self.screen_h/2.,-1, self._far)
        glMatrixMode( GL_MODELVIEW )
        glLoadIdentity()
        glScalef(self.zoom, self.zoom, 1.0)